package com.cocolove2.library_cocodialog.dialogs.base;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.widget.FrameLayout;

import com.cocolove2.library_cocodialog.R;
import com.cocolove2.library_cocodialog.animations.BaseAnimatorEffects;
import com.cocolove2.library_cocodialog.listener.OnAnimListener;

/**
 * 自定义对话框基类<br>
 * 1.支持属性动画,补间动画(属性动画的优先级高于补间动画)<br>
 * 2.支持自定义对话框大小<br>
 * 3.布局灵活设置<br>
 * Created by liubo on 7/28/16.
 */
@SuppressWarnings({"unchecked", "unused"})
public abstract class CocoDialogBase<T extends CocoDialogBase> extends Dialog implements DialogInterface {

    /*用户创建的视图*/
    protected View mOnCreateView;

    protected Context mContext;

    protected boolean isCancelTouchOutSide = true;
    protected boolean isCancelable = true;

    private BaseAnimatorEffects inEffects;
    private BaseAnimatorEffects outEffects;

    private AnimationSet inAnimation;
    private AnimationSet outAnimation;

    private OnAnimListener inAnimListener;
    private OnAnimListener outAnimListener;
    protected boolean isHasExitAnim = false;

    /*对话框的背景色*/
    protected int mDialogBgColor = Color.parseColor("#ffffff");
    /*对话框的四周的圆角弧度 单位:dp*/
    protected float mCornerRadius;


    public CocoDialogBase(Context context) {
        this(context, chooseDialogStyle());
    }

    public CocoDialogBase(Context context, int style) {
        super(context, style);
        mContext = context;
    }

    private static int chooseDialogStyle() {
        return Build.VERSION.SDK_INT < 21 ? R.style.CocoDialogStyle : R.style.CocoDialogStyle_NoStatusBar;
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         /*跟布局*/
        final FrameLayout rootView = new FrameLayout(mContext);
        mOnCreateView = onCreateView(mContext, rootView);
        rootView.addView(mOnCreateView);

        setContentView(rootView);
        /*该方法必须执行于#setContentView#方法之后,不然设置全屏属性会无效*/
        setWindowParams();

        rootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isCancelTouchOutSide) {
                    startOutAnim();
                }
            }
        });
    }

    private void setWindowParams() {
        WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
        getWindow().setAttributes(layoutParams);
    }

    protected abstract View onCreateView(Context context, ViewGroup parent);

    protected abstract void setupUiView();

    public View getOnCreateView() {
        return mOnCreateView;
    }


    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        setCanceledOnTouchOutside(isCancelTouchOutSide);
        setCancelable(isCancelable);
        initInListener();
        initOutListener();
        setupUiView();
        startInAnim();
    }


    /**
     * 设置对话框背景阴影的透明度
     *
     * @param dimAmount 透明度
     * @see Window#setDimAmount(float)
     */
    public void setDimAmount(float dimAmount) {
        getWindow().setDimAmount(dimAmount);

    }


    /**
     * 初始化dialog显示动画监听listener
     */
    protected void initInListener() {
        if (inEffects != null) {
            inEffects.getAnimatorSet().addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (inAnimListener != null)
                        inAnimListener.onAnimStart();
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    if (inAnimListener != null)
                        inAnimListener.onAnimCancel();
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    if (inAnimListener != null)
                        inAnimListener.onAnimEnd();
                }
            });
        } else if (inAnimation != null) {
            inAnimation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    if (inAnimListener != null)
                        inAnimListener.onAnimStart();
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (inAnimListener != null)
                        inAnimListener.onAnimEnd();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        }
    }

    protected boolean isHasExitAnim() {
        return isHasExitAnim;
    }

    /**
     * 初始化dialog退出动画监听
     */
    protected void initOutListener() {
        if (outEffects != null) {
            isHasExitAnim = true;
            outEffects.getAnimatorSet().addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    if (outAnimListener != null)
                        outAnimListener.onAnimStart();
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    if (outAnimListener != null)
                        outAnimListener.onAnimCancel();
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    realDismiss();
                    if (outAnimListener != null)
                        outAnimListener.onAnimEnd();

                }
            });
        } else if (outAnimation != null) {
            isHasExitAnim = true;
            outAnimation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    if (outAnimListener != null)
                        outAnimListener.onAnimStart();
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    realDismiss();
                    if (outAnimListener != null)
                        outAnimListener.onAnimEnd();
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
        } else {
            isHasExitAnim = false;
        }
    }

    @Override
    public void cancel() {
        startOutAnim();
    }

    @Override
    public void dismiss() {
        startOutAnim();
    }

    /**
     * 真正取消对话框(不带退出动画)
     */
    public void realDismiss() {
        mOnCreateView.post(new Runnable() {
            @Override
            public void run() {
                CocoDialogBase.super.dismiss();
            }
        });
    }

    private void startAnimator(BaseAnimatorEffects animator) {
        if (animator != null)
            animator.start(mOnCreateView);
    }

    private void startAnimation(AnimationSet animationSet) {
        if (animationSet != null) {
            mOnCreateView.startAnimation(animationSet);
        }
    }


    protected void startInAnim() {
        if (inEffects != null) {
            startAnimator(inEffects);
        } else if (inAnimation != null) {
            startAnimation(inAnimation);
        }
    }

    private void startOutAnim() {
        if (outEffects != null) {
            startAnimator(outEffects);
        } else if (outAnimation != null) {
            startAnimation(outAnimation);
        } else {
            super.dismiss();
        }
    }

    /**
     * 设置是否可以取消
     * 主要针对{@link Activity#onBackPressed()}
     * 和{@link CocoDialogBase#setCanceledOnTouchOutside(boolean)}独立存在
     */
    public T setCancelabled(boolean cancelable) {
        isCancelable = cancelable;
        return (T) this;
    }

    /**
     * 设置对话框动画(属性动画)<br>
     * 优先级高于{@link CocoDialogBase#setAnimation(AnimationSet, AnimationSet)}
     *
     * @param inEffects  进入动画
     * @param outEffects 退出动画
     */
    public T setAnimator(BaseAnimatorEffects inEffects, BaseAnimatorEffects outEffects) {
        this.inEffects = inEffects;
        this.outEffects = outEffects;
        return (T) this;
    }

    /**
     * 设置对话框动画(补间动画)
     *
     * @param inAnimation  进入动画
     * @param outAnimation 退出动画
     */
    public T setAnimation(AnimationSet inAnimation, AnimationSet outAnimation) {
        this.inAnimation = inAnimation;
        this.outAnimation = outAnimation;
        return (T) this;
    }

    /**
     * 设置点击对话框外部是否可以取消对话框
     */
    public T setCancelTouchOutSide(boolean isCancelTouchOutSide) {
        this.isCancelTouchOutSide = isCancelTouchOutSide;
        return (T) this;
    }

    /**
     * 设置对话框进入动画的监听
     */
    public T setInAnimListener(OnAnimListener inAnimListener) {
        this.inAnimListener = inAnimListener;
        return (T) this;
    }

    protected void setOutAnimListener(OnAnimListener outAnimListener) {
        this.outAnimListener = outAnimListener;
    }

    public T setDialogBgColor(int dialogBgColor) {
        mDialogBgColor = dialogBgColor;
        return (T) this;
    }

    public T setCornerRadius(float cornerRadius) {
        mCornerRadius = dp2px(cornerRadius);
        return (T) this;
    }

    /**
     * dp to px
     */
    protected int dp2px(float dp) {
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    /**
     * 获取对话框默认位置
     *
     * @param gravity           位置
     * @param left_right_margin 左右间距 dp
     * @param top_bottom_margin 上下 dp
     */
    protected FrameLayout.LayoutParams getDefaultParams(int gravity, int left_right_margin, int top_bottom_margin) {
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.gravity = gravity;
        lp.topMargin = lp.bottomMargin = dp2px(top_bottom_margin);
        lp.rightMargin = lp.leftMargin = dp2px(left_right_margin);
        return lp;
    }


    protected FrameLayout.LayoutParams getDefaultparams() {
        return getDefaultParams(Gravity.CENTER, 32, 32);
    }

}

